"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSubkeys = exports.subkeyconstructioner = void 0;
const config_1 = require("./config");
const utils_1 = require("./utils");
/**
 * 使用 自定义的密钥 生成主密钥，在使用主密钥生成子密钥组
 * @param key 自定义的密钥
 * @returns 生成的主密钥，16位，16进制数
 */
function init(key) {
    const buffer = (0, utils_1.getBuffer)(key);
    const newbBuffer = Uint8Array.prototype.slice.call(buffer);
    const mainKey = newbBuffer.slice(0, 8);
    let result = '';
    for (let i = 0; i < mainKey.length; i++) {
        result += (0, utils_1.to16)(mainKey[i]);
    }
    return result;
}
/**
 * 子密钥构造工厂
 * @param binary 主密钥二进制字符串，64位2进制数
 * @returns 子密钥数组
 */
function constructioner(binary) {
    // 进行 PC1 置换
    // const k_plus = pc1Handle(binary)
    // PC1 置换
    const k_plus = (0, utils_1.permutation)(binary, config_1.PU1_TABLE);
    const C0 = k_plus.substring(0, k_plus.length / 2);
    const D0 = k_plus.substring(k_plus.length / 2);
    // 生成密钥对
    const groupKeys = structure16GroupKeys(C0, D0);
    // 生成子密钥
    const subKeys = groupKeysToKeys(groupKeys);
    return subKeys;
}
/**
 * 子密钥构造工厂
 * @param binary 主密钥二进制字符串，64位2进制数
 * @returns 子密钥数组
 */
exports.subkeyconstructioner = constructioner;
/**
 * 构造 16 个密钥对
 * @param C0
 * @param D0
 * @returns 密钥对数组 {C: string, D: string}
 */
function structure16GroupKeys(C0, D0) {
    const groupKeys = [];
    // 定义每次迭代的作用 动作
    const relus = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1];
    relus.forEach((relu, index) => {
        const iteration = index + 1;
        let result = { C: '', D: '' };
        if (iteration !== 1) {
            // @ts-ignore
            const C = groupKeys[index - 1].C;
            // @ts-ignore
            const D = groupKeys[index - 1].D;
            result = leftShift(C, D, relu);
        }
        else {
            // 第一次迭代 使用 C0,D0
            result = leftShift(C0, D0, relu);
        }
        // @ts-ignore
        groupKeys.push(result);
    });
    return groupKeys;
}
/**
 * 二进制左移函数
 * @param C
 * @param D
 * @param size 左移位数，返回密钥对
 * @returns
 */
function leftShift(C, D, size) {
    // 移动 C
    const sub_C = C.substring(0, size);
    const result_C = (C + sub_C).substring(size);
    // 移动 D
    const sub_D = D.substring(0, size);
    const result_D = (D + sub_D).substring(size);
    return {
        C: result_C,
        D: result_D
    };
}
// 密钥对转密钥
function groupKeysToKeys(groupKeys) {
    const keys = [];
    groupKeys.forEach((item, index) => {
        // @ts-ignore
        const CD = item.C + item.D;
        let k = '';
        config_1.PU2_TABLE.forEach(n => {
            k += CD.substring(n - 1, n);
        });
        keys.push(k);
    });
    return keys;
}
// 创建 子密钥数组
function createSubkeys(key) {
    // 主密钥，长度为 16的16进制数
    const mainKey = init(key);
    // 将主密钥转为2进制。64位2进制数
    const binary = (0, utils_1.getBinary)(mainKey);
    // 子密钥数组
    const subkeys = constructioner(binary);
    return subkeys;
}
exports.createSubkeys = createSubkeys;
